Make CargoError inherit from Send
authorAlex Crichton <alex@alexcrichton.com>
Sat, 28 Jun 2014 23:55:02 +0000 (16:55 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 30 Jun 2014 23:00:33 +0000 (16:00 -0700)
Due to a bug in the compiler, this also requires adding `+ Send` any time that
CargoError is mentioned. This change will allow errors to be sent across tasks.

src/cargo/core/package_id.rs
src/cargo/util/errors.rs
src/cargo/util/result.rs

index 719c709a5dba63afd6f7ddf6947b99af8bbe8852..1a421fe636f77873b8630eda2445d29c480e4bf8 100644 (file)
@@ -115,8 +115,11 @@ impl Show for PackageId {
     }
 }
 
-impl<D: Decoder<Box<CargoError>>> Decodable<D,Box<CargoError>> for PackageId {
-    fn decode(d: &mut D) -> Result<PackageId, Box<CargoError>> {
+impl<D: Decoder<Box<CargoError + Send>>>
+    Decodable<D,Box<CargoError + Send>>
+    for PackageId
+{
+    fn decode(d: &mut D) -> Result<PackageId, Box<CargoError + Send>> {
         let vector: Vec<String> = match Decodable::decode(d) {
             Ok(v) => v,
             Err(e) => return Err(e.to_error())
index 09035efce885b3cb2e4f7dad216cd377a085cda7..e67f9c0cf64ded595bd5e528a92eace02bbfc996 100644 (file)
@@ -6,39 +6,39 @@ use std::str;
 
 use TomlError = toml::Error;
 
-pub trait CargoError {
+pub trait CargoError: Send {
     fn description(&self) -> String;
     fn detail(&self) -> Option<String> { None }
-    fn cause<'a>(&'a self) -> Option<&'a CargoError> { None }
+    fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> { None }
     fn is_human(&self) -> bool { false }
 
     fn to_error<E: FromError<Self>>(self) -> E {
         FromError::from_error(self)
     }
 
-    fn box_error(self) -> Box<CargoError> {
-        box self as Box<CargoError>
+    fn box_error(self) -> Box<CargoError + Send> {
+        box self as Box<CargoError + Send>
     }
 
     fn concrete(&self) -> ConcreteCargoError {
         ConcreteCargoError {
             description: self.description(),
             detail: self.detail(),
-            cause: self.cause().map(|c| box c.concrete() as Box<CargoError>),
+            cause: self.cause().map(|c| box c.concrete() as Box<CargoError + Send>),
             is_human: self.is_human()
         }
     }
 
-    fn with_cause<E: CargoError>(self, cause: E) -> Box<CargoError> {
+    fn with_cause<E: CargoError + Send>(self, cause: E) -> Box<CargoError + Send> {
         let mut concrete = self.concrete();
         concrete.cause = Some(cause.box_error());
-        box concrete as Box<CargoError>
+        box concrete as Box<CargoError + Send>
     }
 
-    fn mark_human(self) -> Box<CargoError> {
+    fn mark_human(self) -> Box<CargoError + Send> {
         let mut concrete = self.concrete();
         concrete.is_human = true;
-        box concrete as Box<CargoError>
+        box concrete as Box<CargoError + Send>
     }
 }
 
@@ -46,8 +46,8 @@ pub trait FromError<E> {
     fn from_error(error: E) -> Self;
 }
 
-impl<E: CargoError> FromError<E> for Box<CargoError> {
-    fn from_error(error: E) -> Box<CargoError> {
+impl<E: CargoError + Send> FromError<E> for Box<CargoError + Send> {
+    fn from_error(error: E) -> Box<CargoError + Send> {
         error.box_error()
     }
 }
@@ -69,7 +69,7 @@ impl Show for Box<CargoError> {
     }
 }
 
-impl CargoError for Box<CargoError> {
+impl CargoError for Box<CargoError + Send> {
     fn description(&self) -> String {
         (*self).description()
     }
@@ -78,7 +78,7 @@ impl CargoError for Box<CargoError> {
         (*self).detail()
     }
 
-    fn cause<'a>(&'a self) -> Option<&'a CargoError> {
+    fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> {
         (*self).cause()
     }
 
@@ -86,35 +86,35 @@ impl CargoError for Box<CargoError> {
         (*self).is_human()
     }
 
-    fn box_error(self) -> Box<CargoError> {
+    fn box_error(self) -> Box<CargoError + Send> {
         self
     }
 }
 
-pub type CargoResult<T> = Result<T, Box<CargoError>>;
+pub type CargoResult<T> = Result<T, Box<CargoError + Send>>;
 
 pub trait BoxError<T> {
     fn box_error(self) -> CargoResult<T>;
 }
 
 pub trait ChainError<T> {
-    fn chain_error<E: CargoError>(self, callback: || -> E) -> CargoResult<T> ;
+    fn chain_error<E: CargoError + Send>(self, callback: || -> E) -> CargoResult<T> ;
 }
 
 impl<'a, T> ChainError<T> for ||:'a -> CargoResult<T> {
-    fn chain_error<E: CargoError>(self, callback: || -> E) -> CargoResult<T> {
+    fn chain_error<E: CargoError + Send>(self, callback: || -> E) -> CargoResult<T> {
         self().map_err(|err| callback().with_cause(err))
     }
 }
 
-impl<T, E: CargoError> BoxError<T> for Result<T, E> {
+impl<T, E: CargoError + Send> BoxError<T> for Result<T, E> {
     fn box_error(self) -> CargoResult<T> {
         self.map_err(|err| err.box_error())
     }
 }
 
-impl<T, E: CargoError> ChainError<T> for Result<T, E> {
-    fn chain_error<E: CargoError>(self, callback: || -> E) -> CargoResult<T>  {
+impl<T, E: CargoError + Send> ChainError<T> for Result<T, E> {
+    fn chain_error<E: CargoError + Send>(self, callback: || -> E) -> CargoResult<T>  {
         self.map_err(|err| callback().with_cause(err))
     }
 }
@@ -144,7 +144,7 @@ pub struct ProcessError {
     pub exit: Option<ProcessExit>,
     pub output: Option<ProcessOutput>,
     pub detail: Option<String>,
-    pub cause: Option<Box<CargoError>>
+    pub cause: Option<Box<CargoError + Send>>
 }
 
 from_error!(ProcessError)
@@ -184,20 +184,21 @@ impl CargoError for ProcessError {
         self.detail.clone()
     }
 
-    fn cause<'a>(&'a self) -> Option<&'a CargoError> {
-        self.cause.as_ref().map(|c| { let err: &CargoError = *c; err })
+    fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> {
+        self.cause.as_ref().map(|c| { let err: &CargoError + Send = *c; err })
     }
 
-    fn with_cause<E: CargoError>(mut self, err: E) -> Box<CargoError> {
+    fn with_cause<E: CargoError + Send>(mut self,
+                                        err: E) -> Box<CargoError + Send> {
         self.cause = Some(err.box_error());
-        box self as Box<CargoError>
+        box self as Box<CargoError + Send>
     }
 }
 
 pub struct ConcreteCargoError {
     description: String,
     detail: Option<String>,
-    cause: Option<Box<CargoError>>,
+    cause: Option<Box<CargoError + Send>>,
     is_human: bool
 }
 
@@ -216,18 +217,19 @@ impl CargoError for ConcreteCargoError {
         self.detail.clone()
     }
 
-    fn cause<'a>(&'a self) -> Option<&'a CargoError> {
-        self.cause.as_ref().map(|c| { let err: &CargoError = *c; err })
+    fn cause<'a>(&'a self) -> Option<&'a CargoError + Send> {
+        self.cause.as_ref().map(|c| { let err: &CargoError + Send = *c; err })
     }
 
-    fn with_cause<E: CargoError>(mut self, err: E) -> Box<CargoError> {
+    fn with_cause<E: CargoError + Send>(mut self,
+                                        err: E) -> Box<CargoError + Send> {
         self.cause = Some(err.box_error());
-        box self as Box<CargoError>
+        box self as Box<CargoError + Send>
     }
 
-    fn mark_human(mut self) -> Box<CargoError> {
+    fn mark_human(mut self) -> Box<CargoError + Send> {
         self.is_human = true;
-        box self as Box<CargoError>
+        box self as Box<CargoError + Send>
     }
 
     fn is_human(&self) -> bool {
@@ -239,7 +241,7 @@ pub type CliResult<T> = Result<T, CliError>;
 
 #[deriving(Show)]
 pub struct CliError {
-    pub error: Box<CargoError>,
+    pub error: Box<CargoError + Send>,
     pub unknown: bool,
     pub exit_code: uint
 }
@@ -259,11 +261,11 @@ impl CliError {
     }
 
     pub fn from_error<E: CargoError + 'static>(error: E, code: uint) -> CliError {
-        let error = box error as Box<CargoError>;
+        let error = box error as Box<CargoError + Send>;
         CliError::from_boxed(error, code)
     }
 
-    pub fn from_boxed(error: Box<CargoError>, code: uint) -> CliError {
+    pub fn from_boxed(error: Box<CargoError + Send>, code: uint) -> CliError {
         let human = error.is_human();
         CliError { error: error, exit_code: code, unknown: !human }
     }
@@ -278,34 +280,34 @@ pub fn process_error<S: Str>(msg: S,
         exit: status.map(|o| o.clone()),
         output: output.map(|o| o.clone()),
         detail: None,
-        cause: cause.map(|c| box c as Box<CargoError>)
+        cause: cause.map(|c| box c as Box<CargoError + Send>)
     }
 }
 
 pub fn internal_error<S1: Str, S2: Str>(error: S1,
-                                        detail: S2) -> Box<CargoError> {
+                                        detail: S2) -> Box<CargoError + Send> {
     box ConcreteCargoError {
         description: error.as_slice().to_str(),
         detail: Some(detail.as_slice().to_str()),
         cause: None,
         is_human: false
-    } as Box<CargoError>
+    } as Box<CargoError + Send>
 }
 
-pub fn internal<S: Show>(error: S) -> Box<CargoError> {
+pub fn internal<S: Show>(error: S) -> Box<CargoError + Send> {
     box ConcreteCargoError {
         description: error.to_str(),
         detail: None,
         cause: None,
         is_human: false
-    } as Box<CargoError>
+    } as Box<CargoError + Send>
 }
 
-pub fn human<S: Show>(error: S) -> Box<CargoError> {
+pub fn human<S: Show>(error: S) -> Box<CargoError + Send> {
     box ConcreteCargoError {
         description: error.to_str(),
         detail: None,
         cause: None,
         is_human: true
-    } as Box<CargoError>
+    } as Box<CargoError + Send>
 }
index d47ca51e87f7842bbc816bbb2677e797eb71ab0b..108e08488d441feb3e7f2a84b82d7bc47a96a49e 100644 (file)
@@ -1,11 +1,11 @@
 use util::errors::{CargoResult, CargoError};
 
 pub trait Wrap {
-    fn wrap<E: CargoError>(self, error: E) -> Self;
+    fn wrap<E: CargoError + Send>(self, error: E) -> Self;
 }
 
-impl<T> Wrap for Result<T, Box<CargoError>> {
-    fn wrap<E: CargoError>(self, error: E) -> CargoResult<T> {
+impl<T> Wrap for Result<T, Box<CargoError + Send>> {
+    fn wrap<E: CargoError + Send>(self, error: E) -> CargoResult<T> {
         match self {
             Ok(x) => Ok(x),
             Err(e) => Err(error.with_cause(e))
@@ -14,14 +14,14 @@ impl<T> Wrap for Result<T, Box<CargoError>> {
 }
 
 pub trait Require<T> {
-    fn require<E: CargoError>(self, err: || -> E) -> CargoResult<T>;
+    fn require<E: CargoError + Send>(self, err: || -> E) -> CargoResult<T>;
 }
 
 impl<T> Require<T> for Option<T> {
-    fn require<E: CargoError>(self, err: || -> E) -> CargoResult<T> {
+    fn require<E: CargoError + Send>(self, err: || -> E) -> CargoResult<T> {
         match self {
             Some(x) => Ok(x),
-            None => Err(box err().concrete() as Box<CargoError>)
+            None => Err(box err().concrete() as Box<CargoError + Send>)
         }
     }
 }